package sunwin.yoms.service.system;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import sunwin.yoms.comm.YomsException;
import sunwin.yoms.dao.SysFunctionDao;
import sunwin.yoms.domain.person.UserRoleDomain;
import sunwin.yoms.domain.system.SysFunctionDomain;
import sunwin.yoms.service.person.RoleService;

import java.util.*;

/**
 * Created by watson on 2015/7/29.
 */
@Service
public class SysFunctionService {
    @Autowired
    private SysFunctionDao sysFunctionDao;
    @Autowired
    private RoleService roleService;

    private Map<Integer, SysFunctionDomain> allDomains = null;   //系统
    private List<SysFunctionDomain> domains1 = null;   //宣传模块
    private List<SysFunctionDomain> domains2 = null;   //设施资源模块
    private List<SysFunctionDomain> domains3 = null;   //人员模块
    private List<SysFunctionDomain> domains4 = null;   //系统配置模块

    public void initFunc() throws YomsException {
        getPublictyFunction();
        getPersonFunction();
        getFacilityFunction();
        getSettingFunction();

        if (allDomains == null) {
            allDomains = new HashMap<>();
        }

        try {
            for (SysFunctionDomain domain : domains1) {
                allDomains.put(domain.getSysFuncId(), domain);
            }
            for (SysFunctionDomain domain : domains2) {
                allDomains.put(domain.getSysFuncId(), domain);
            }
            for (SysFunctionDomain domain : domains3) {
                allDomains.put(domain.getSysFuncId(), domain);
            }
            for (SysFunctionDomain domain : domains4) {
                allDomains.put(domain.getSysFuncId(), domain);
            }
        } catch (Exception e) {
            allDomains.clear();
        }
    }

    /**
     * 为角色分配功能
     *
     * @param rid     角色id
     * @param fid     功能id
     * @param isAllot 是否分配; true表示分配功能; false表示取消撤销功能
     * @throws YomsException
     */
    public void setRoleFunc(int rid, int fid, boolean isAllot) throws YomsException {
        SysFunctionDomain domain = this.getFuncById(fid);
        if (isAllot) {
            roleService.addRoleFunc(rid, domain);
        } else {
            roleService.removeRoleFunc(rid, domain);
        }
    }

    /**
     * 根据角色获取权限
     *
     * @param role 用户角色
     * @return
     * @throws YomsException
     */
    public Map<Integer, Boolean> getRoleFunc(UserRoleDomain role) throws YomsException {
        this.initFunc();

        Map<Integer, Boolean> map = new HashMap<Integer, Boolean>();
        Iterator<Integer> keys = allDomains.keySet().iterator();
        while (keys.hasNext()) {
            SysFunctionDomain domain = allDomains.get(keys.next());
            long roleFunc = role.getUserRoleFunction0();
            long funcValue = domain.getSysFuncValue();
            map.put(domain.getSysFuncId(), (roleFunc & funcValue) == funcValue);
        }

        return map;
    }

    /**
     * 根据角色集合获取权限列表
     *
     * @param roles
     * @return
     */
    public List<SysFunctionDomain> getRoleFunction(List<UserRoleDomain> roles) throws YomsException {
        this.initFunc();

        SysFunctionDomain sysFunction = null;
        sysFunction = new SysFunctionDomain();
        sysFunction.setSysFuncNo("ROLE_USER");

        List<SysFunctionDomain> functions = new ArrayList<>();
        functions.add(sysFunction);

        for (UserRoleDomain role : roles) {
            Iterator<Integer> keys = allDomains.keySet().iterator();
            while (keys.hasNext()) {
                SysFunctionDomain domain = allDomains.get(keys.next());
                long roleFunc = role.getUserRoleFunction0();
                long funcValue = domain.getSysFuncValue();
                if ((roleFunc & funcValue) == funcValue) {
                    functions.add(domain);
                    Logger.getLogger(this.getClass()).debug(String.format("functionNo=%s&functionName=%s", domain.getSysFuncNo(), domain.getSysFuncName()));
                }
            }
        }
        return functions;
    }

    /**
     * 根据编号获取功能
     * @param functionNo
     * @return
     * @throws YomsException
     */
    public SysFunctionDomain getFuncByNo(String functionNo) throws YomsException {
        this.initFunc();

        SysFunctionDomain domain = null;

        Iterator<Integer> keys = allDomains.keySet().iterator();
        while (keys.hasNext()) {
            SysFunctionDomain tempDomain = allDomains.get(keys.next());
            if(tempDomain.getSysFuncNo().equals(functionNo)){
                domain = tempDomain;
            }
        }

        if(domain == null){
            throw YomsException.getInstance(String.format("无法查找到编号为%s的功能", functionNo));
        }

        return domain;
    }

    /**
     * 宣传模块功能
     *
     * @return
     */
    public List<SysFunctionDomain> getPublictyFunction() throws YomsException {
        if (domains1 == null) {
            List<SysFunctionDomain> fs = this.getFunctions(2);
            if (fs.isEmpty()) {
                throw new YomsException("获取宣传管理模块功能失败");
            } else {
                domains1 = fs;
            }
        }

        return domains1;
    }

    /**
     * 设施资源模块功能
     *
     * @return
     */
    public List<SysFunctionDomain> getFacilityFunction() throws YomsException {
        if (domains2 == null) {
            List<SysFunctionDomain> fs = this.getFunctions(3);
            if (fs.isEmpty()) {
                throw new YomsException("获取设施资源管理模块功能失败");
            } else {
                domains2 = fs;
            }
        }

        return domains2;
    }

    /**
     * 人员管理模块功能
     *
     * @return
     */
    public List<SysFunctionDomain> getPersonFunction() throws YomsException {
        if (domains3 == null) {
            List<SysFunctionDomain> fs = this.getFunctions(1);
            if (fs.isEmpty()) {
                throw new YomsException("获取人员管理模块功能失败");
            } else {
                domains3 = fs;
            }
        }

        return domains3;
    }

    /**
     * 系统配置模块功能
     *
     * @return
     */
    public List<SysFunctionDomain> getSettingFunction() throws YomsException {
        if (domains4 == null) {
            List<SysFunctionDomain> fs = this.getFunctions(4);
            if (fs.isEmpty()) {
                throw new YomsException("获取系统配置模块功能失败");
            } else {
                domains4 = fs;
            }
        }

        return domains4;
    }

    /**
     * 根据功能id查找功能
     *
     * @param fid
     * @return
     */
    public SysFunctionDomain getFuncById(int fid) throws YomsException {
        SysFunctionDomain domain = sysFunctionDao.getDomainById(fid);
        if (domain == null) {
            throw new YomsException("无法找到指定功能");
        }
        return domain;
    }

    /**
     * 根据模块获取系统功能
     *
     * @param owner 模块标识
     * @return
     */
    private List<SysFunctionDomain> getFunctions(int owner) {
        SysFunctionDomain domain = new SysFunctionDomain();
        domain.setSysFuncOwner(owner);

        List<SysFunctionDomain> sysFunctionDomains = sysFunctionDao.getDomainByCondition(domain);

        return sysFunctionDomains;
    }
}
